#include "websocket_event_processor.h"
#include "base_log.h"
#include "device_protocol_processor.h"
#include <chrono>
#include <random>

namespace El {
namespace Protocol {

WebSocketEventProcessor &WebSocketEventProcessor::GetInstance()
{
    static WebSocketEventProcessor instance;
    static bool initialized = false;
    
    if (!initialized) {
        instance.InitMethodHandlers();
        initialized = true;
    }
    
    return instance;
}

void WebSocketEventProcessor::InitMethodHandlers()
{
    // 注册认证相关方法处理器
    method_handlers_["auth.getChallenge"] = [this](const std::string &id, const nlohmann::json &params) {
        return HandleAuthGetChallenge(id, params);
    };
    
    method_handlers_["auth.login"] = [this](const std::string &id, const nlohmann::json &params) {
        return HandleAuthLogin(id, params);
    };
    
    method_handlers_["auth.refreshToken"] = [this](const std::string &id, const nlohmann::json &params) {
        return HandleAuthRefreshToken(id, params);
    };
    
    method_handlers_["auth.logout"] = [this](const std::string &id, const nlohmann::json &params) {
        return HandleAuthLogout(id, params);
    };
    
    method_handlers_["auth.getSessions"] = [this](const std::string &id, const nlohmann::json &params) {
        return HandleAuthGetSessions(id, params);
    };
    
    // 注册设备协议处理器
    auto &device_processor = DeviceProtocolProcessor::GetInstance();
    if (!device_processor.Initialize()) {
        LOG_ERROR("初始化设备协议处理器失败");
    }
    
    // 注册设备管理相关方法处理器
    device_processor.RegisterMethodHandlers(method_handlers_);
}

std::string WebSocketEventProcessor::ProcessEvent(std::shared_ptr<El::WebServer::WebSocketEvent> &event)
{
    LOG_DEBUG("Processing WebSocket event: {}", event->message);
    
    try {
        std::string id;
        std::string method;
        nlohmann::json params;
        
        // 解析请求
        if (!ParseRequest(event->message, id, method, params)) {
            LOG_ERROR("Failed to parse WebSocket request: {}", event->message);
            auto error_response = CreateErrorResponse("", -32700, "Parse error");
            return error_response.dump();
        }
        
        LOG_DEBUG("Parsed request - id: {}, method: {}", id, method);
        
        // 查找对应的方法处理器
        auto handler_it = method_handlers_.find(method);
        if (handler_it == method_handlers_.end()) {
            LOG_ERROR("Method not found: {}", method);
            auto error_response = CreateErrorResponse(id, -32601, "Method not found");
            return error_response.dump();
        }
        
        // 调用方法处理器
        nlohmann::json response;
        try {
            response = handler_it->second(id, params);
        } catch (const std::exception &e) {
            LOG_ERROR("Error processing method {}: {}", method, e.what());
            auto error_response = CreateErrorResponse(id, -32603, "Internal error", nlohmann::json(e.what()));
            return error_response.dump();
        }
        
        // 返回处理结果
        return response.dump();
    } catch (const std::exception &e) {
        LOG_ERROR("Exception in ProcessEvent: {}", e.what());
        auto error_response = CreateErrorResponse("", -32603, "Internal error");
        return error_response.dump();
    }
}

bool WebSocketEventProcessor::ParseRequest(const std::string &message, std::string &id, 
                                          std::string &method, nlohmann::json &params)
{
    try {
        nlohmann::json request = nlohmann::json::parse(message);
        
        // 检查必需字段
        if (!request.contains("method") || !request["method"].is_string()) {
            return false;
        }
        
        // 获取请求字段
        method = request["method"].get<std::string>();
        
        // ID可能是字符串或数字
        if (request.contains("id")) {
            if (request["id"].is_string()) {
                id = request["id"].get<std::string>();
            } else if (request["id"].is_number()) {
                id = std::to_string(request["id"].get<int>());
            } else {
                return false;
            }
        } else {
            id = ""; // 通知类消息可能没有ID
        }
        
        // 获取参数，如果没有则为空对象
        if (request.contains("params") && request["params"].is_object()) {
            params = request["params"];
        } else {
            params = nlohmann::json::object();
        }
        
        return true;
    } catch (const std::exception &e) {
        LOG_ERROR("Exception in ParseRequest: {}", e.what());
        return false;
    }
}

nlohmann::json WebSocketEventProcessor::CreateErrorResponse(const std::string &id, int code, 
                                                          const std::string &message, 
                                                          const nlohmann::json &data)
{
    nlohmann::json error = {
        {"code", code},
        {"message", message}
    };
    
    if (data != nullptr) {
        error["data"] = data;
    }
    
    nlohmann::json response = {
        {"id", id},
        {"error", error}
    };
    
    return response;
}

nlohmann::json WebSocketEventProcessor::CreateSuccessResponse(const std::string &id, 
                                                            const nlohmann::json &result)
{
    return {
        {"id", id},
        {"result", result}
    };
}

// 认证方法实现
nlohmann::json WebSocketEventProcessor::HandleAuthGetChallenge(const std::string &id, 
                                                             const nlohmann::json &params)
{
    // 检查参数
    if (!params.contains("username") || !params["username"].is_string()) {
        return CreateErrorResponse(id, 400, "Bad Request", "Missing or invalid username");
    }
    
    std::string username = params["username"];
    std::string device_id;
    
    if (params.contains("device_id") && params["device_id"].is_string()) {
        device_id = params["device_id"];
    }
    
    // 生成随机挑战码
    const std::string chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
    std::random_device rd;
    std::mt19937 generator(rd());
    std::uniform_int_distribution<> distribution(0, chars.size() - 1);
    
    std::string challenge;
    for (int i = 0; i < 32; ++i) {
        challenge += chars[distribution(generator)];
    }
    
    // TODO: 存储挑战码，关联到用户名和设备ID
    
    nlohmann::json result = {
        {"challenge", challenge},
        {"expires_in", 300}
    };
    
    return CreateSuccessResponse(id, result);
}

nlohmann::json WebSocketEventProcessor::HandleAuthLogin(const std::string &id, 
                                                      const nlohmann::json &params)
{
    // 简单实现，真实环境需要完善验证逻辑
    LOG_DEBUG("Auth login request received");
    
    // 检查必需参数
    if (!params.contains("username") || !params["username"].is_string() ||
        !params.contains("credential") || !params["credential"].is_string() ||
        !params.contains("challenge") || !params["challenge"].is_string()) {
        return CreateErrorResponse(id, 400, "Bad Request", "Missing required parameters");
    }
    
    // TODO: 验证凭证，生成token等逻辑
    
    // 模拟成功登录响应
    nlohmann::json user = {
        {"id", "user-123"},
        {"username", params["username"]},
        {"role", "administrator"},
        {"permissions", nlohmann::json::array({"camera.view", "camera.control"})},
        {"last_login", "2024-03-20T02:00:00Z"},
        {"last_login_ip", "192.168.1.100"}
    };
    
    nlohmann::json result = {
        {"access_token", "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.example.token"},
        {"refresh_token", "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.example.refresh.token"},
        {"token_type", "Bearer"},
        {"expires_in", 3600},
        {"user", user}
    };
    
    return CreateSuccessResponse(id, result);
}

nlohmann::json WebSocketEventProcessor::HandleAuthRefreshToken(const std::string &id, 
                                                            const nlohmann::json &params)
{
    // 简单实现，真实环境需要完善验证逻辑
    if (!params.contains("refresh_token") || !params["refresh_token"].is_string()) {
        return CreateErrorResponse(id, 400, "Bad Request", "Missing refresh_token");
    }
    
    // TODO: 验证refresh_token
    
    nlohmann::json result = {
        {"access_token", "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.new.example.token"},
        {"token_type", "Bearer"},
        {"expires_in", 3600}
    };
    
    return CreateSuccessResponse(id, result);
}

nlohmann::json WebSocketEventProcessor::HandleAuthLogout(const std::string &id, 
                                                       const nlohmann::json &params)
{
    // 简单实现
    std::string device_id;
    bool logout_all = false;
    
    if (params.contains("device_id") && params["device_id"].is_string()) {
        device_id = params["device_id"];
    }
    
    if (params.contains("logout_all") && params["logout_all"].is_boolean()) {
        logout_all = params["logout_all"];
    }
    
    // TODO: 实际登出处理逻辑
    
    nlohmann::json result;
    if (logout_all) {
        result["logged_out_devices"] = nlohmann::json::array({"device_id1", "device_id2"});
    } else {
        result["logged_out_devices"] = nlohmann::json::array({device_id});
    }
    
    return CreateSuccessResponse(id, result);
}

nlohmann::json WebSocketEventProcessor::HandleAuthGetSessions(const std::string &id, 
                                                           const nlohmann::json &params)
{
    // 简单实现 - 返回示例会话数据
    nlohmann::json session1 = {
        {"device_id", "unique_device_id1"},
        {"device_info", {
            {"type", "browser"},
            {"os", "Windows"},
            {"client", "Chrome 120.0.0"}
        }},
        {"ip", "192.168.1.100"},
        {"login_time", "2024-03-20T02:00:00Z"},
        {"last_active", "2024-03-20T02:30:00Z"},
        {"is_current", true}
    };
    
    nlohmann::json session2 = {
        {"device_id", "unique_device_id2"},
        {"device_info", {
            {"type", "mobile"},
            {"os", "iOS"},
            {"client", "App 1.0.0"}
        }},
        {"ip", "192.168.1.101"},
        {"login_time", "2024-03-19T10:00:00Z"},
        {"last_active", "2024-03-20T01:30:00Z"},
        {"is_current", false}
    };
    
    nlohmann::json result = {
        {"total", 2},
        {"sessions", nlohmann::json::array({session1, session2})}
    };
    
    return CreateSuccessResponse(id, result);
}

} // namespace Protocol
} // namespace El
